-- Copyright (c) 2025 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local class = require 'mc.class'
local singleton = require 'mc.singleton'
local service = require 'spdm.service'
local cert_config = require 'cert_config'

local certificate_mdb = class()

function certificate_mdb:ctor(responder_collection)
    self.m_responder_collection = responder_collection
    self.m_mdb_certs = {}
end

function certificate_mdb:init()
    self:regist_signals()
end

function certificate_mdb:regist_signals()
    self.m_responder_collection.m_cert_added:on(function(...)
        self:new_cert_to_mdb(...)
    end)
end

local function key_usage_to_enum(key_usage)
    local usages = {}
    for bit, enumValue in pairs(cert_config.KU_BIT_MAP) do
        if key_usage & bit ~= 0 then
            table.insert(usages, enumValue)
        end
    end

    return usages
end

function certificate_mdb:new_cert_to_mdb(slot_id, info)
    local cert_obj = service:CreateTrustedComponentCertificate(tostring(info.m_chassis_id), info.m_mdb_name,
        tostring(slot_id + 1), function(cur_obj)
        cur_obj.CertificateType          = info.m_cert_info.certificateType
        cur_obj.CertificateUsageType     = info.m_cert_info.certificateUsageType
        cur_obj.Fingerprint              = info.m_cert_info.fingerPrint
        cur_obj.FingerprintHashAlgorithm = info.m_cert_info.fingerPrintHashAlgorithm
        cur_obj.Issuer                   = info.m_cert_info.issuer
        cur_obj.Subject                  = info.m_cert_info.subject
        cur_obj.SerialNumber             = info.m_cert_info.serialNumber
        cur_obj.SignatureAlgorithm       = info.m_cert_info.signatureAlgorithm
        cur_obj.ValidNotBefore           = os.date("!%b %d %Y UTC", info.m_cert_info.validNotBefore)
        cur_obj.ValidNotAfter            = os.date("!%b %d %Y UTC", info.m_cert_info.validNotAfter)
        cur_obj.CertCount                = info.m_cert_info.certCount
        cur_obj.KeyLength                = info.m_cert_info.keyLength
        cur_obj.CommonName               = info.m_cert_info.commonName
        cur_obj.FilePath                 = ""
        cur_obj.KeyUsage                 = key_usage_to_enum(info.m_cert_info.keyUsage)
    end)
    self.m_mdb_certs[#self.m_mdb_certs] = cert_obj
end

return singleton(certificate_mdb)